#!/usr/bin/python

import unittest

import layout_parser
from widgets import atoms


class LayoutParserTests(unittest.TestCase):
  def test_parse_one_program(self):
    code = """
( (button:32x32)|(button:32x?)|(button:32x?)|():10x?|(button:32x?)|(button:32x?)|()
  ---------------------------------------------------------------------------------
                                     (textbox)
  ---------------------------------------------------------------------------------
                                (label)|(button:40x20)                              ) :300x200
    """
    parsed = layout_parser.parse(code)
    main_window = parsed["main_window"]

    self.assertEquals(len(main_window), 3)
    
    self.assertEquals(len(main_window[0]), 7)
    self.assertEquals(main_window[0].calculate_size(), (300, 32))
    self.assertEquals(main_window[0][0].calculate_size(), (32, 32))
    self.assertEquals(type(main_window[0][0]), atoms.Button)
    self.assertEquals(main_window[0][1].calculate_size(), (32, 32))
    self.assertEquals(type(main_window[0][1]), atoms.Button)
    self.assertEquals(main_window[0][2].calculate_size(), (32, 32))
    self.assertEquals(type(main_window[0][2]), atoms.Button)
    self.assertEquals(main_window[0][3].calculate_size(), (10, 32))
    self.assertEquals(type(main_window[0][3]), atoms.EmptyBox)
    self.assertEquals(main_window[0][4].calculate_size(), (32, 32))
    self.assertEquals(type(main_window[0][4]), atoms.Button)
    self.assertEquals(main_window[0][5].calculate_size(), (32, 32))
    self.assertEquals(type(main_window[0][5]), atoms.Button)
    self.assertEquals(type(main_window[0][6]), atoms.EmptyBox)

    self.assertEquals(type(main_window[1]), atoms.TextBox)
    self.assertEquals(main_window[1].calculate_size(), (300, 148))

    self.assertEquals(len(main_window[2]), 2)
    self.assertEquals(type(main_window[2][0]), atoms.Label)
    self.assertEquals(main_window[2][1].calculate_size(), (40, 20))
    self.assertEquals(type(main_window[2][1]), atoms.Button)
    
  def test_parse_sub_programs(self):
    code = """
L <- (             (label:13x1)
      -------------------------------------
      (button)|(label:3x1)|(button)|(label:2x1))

I <- (textbox:32x32)

main_window <- ((L)|(I))
    """
    parsed = layout_parser.parse(code)
    # TODO(mishas): complete test.

  def test_parse_attributes(self):
    code = """
L <- (                           (label)[text="Do you like?"]
      --------------------------------------------------------------------------------------
      (radio)[checked=x]|(label:3x1)[text="Yes"]|(radio)[checked=(!x && (x || !x))]|(label:2x1)[text="No"])

I <- (textbox:32x32)

main_window <- ((L)|(I))
    """
    parsed = layout_parser.parse(code)
    # TODO(mishas): complete tests.

  def test_widget_minimal_set(self):
    minimal_set = (
        ("()", atoms.EmptyBox),
        ("label", atoms.Label),
        ("textbox", atoms.TextBox),
        ("button", atoms.Button),
        ("radio", atoms.Radio),
        ("checkbox", atoms.CheckBox),
        ("image", atoms.Image), 
        ("combobox", atoms.ComboBox),
        ("slider", atoms.Slider)
     )
    for widget_name, widget_class in minimal_set:
      code = "(%s:10x10)" % widget_name
      parsed = layout_parser.parse(code)
      main_window = parsed["main_window"]
      self.assertEquals(type(main_window), widget_class)
  
  def test_widget_unknown(self):
    code = "(unknown_widget:20x20)"
    parsed = layout_parser.parse(code)
    self.assertIsNone(parsed)
  """
  def test_attributes_min_set(self):
    attribute_dict = {
        "label": ("text", "font", "image", "halign", "valign"),
        "textbox": ("text", "font", "enabled", "halign", "valign", "fgcolor", "bgcolor"),
        "button": ("enabled"),
        "radio": ("enabled", "checked"),
        "checkbox": ("enabled", "checked"),   
        "image": ("image"),
        "combobox": ("text", "font"),
        "slider": ("value", "minvalue", "maxvalue")
    }
    for widget_name, attributes in attribute_dict.iteritems():
      for attribute_name in attributes:
        code = '(%s:10x10)[%s=""]' % (widget_name, attributes)
        parsed = layout_parser.parse(code)
        main_window = parsed["main_window"]
        pass
         
   """
  def label_native_dimensions_init(self): 
    label_without_size = """
    (label)[text="supercalifragilisticexpialidocious"] 
    """
    parsed_label_without_size = layout_parser.parse(label_without_size)
    main_window_label_without_size = parsed_label_without_size["main_window"]
    
    label_with_questions_mark = """
    ( (label:?x?)[text="supercalifragilisticexpialidocious"] ) : 274x14
    """
    parsed_label_with_questions_mark = layout_parser.parse(label_with_questions_mark)
    main_window_label_with_quastions_mark = parsed_label_with_questions_mark["main_window"]
    return main_window_label_without_size, main_window_label_with_quastions_mark 
  
  def test_native_dimensions_without_size_label(self):
    main_window_label_without_size, main_window_label_with_quastions_mark = self.label_native_dimensions_init()
    self.assertEquals(main_window_label_without_size.calculate_size(), main_window_label_without_size.calculate_box_size())

  
  def test_native_dimensions_with_queasion_marks_label(self):
    main_window_label_without_size, main_window_label_with_quastions_mark = self.label_native_dimensions_init()
    self.assertEquals(main_window_label_with_quastions_mark.calculate_size(), main_window_label_with_quastions_mark.calculate_box_size())
    self.assertEquals(main_window_label_with_quastions_mark.calculate_size(), (274, 14))     # width, height for text according to paint
  
  def image_native_dimensions_init(self): 
    image_without_size = """
    ( (image)[image="http://www.adobetes.com/f45iaw100/ex1_02_video.flv"] ) :50x50
    """
    parsed_image_without_size = layout_parser.parse(image_without_size)
    main_window_image_without_size = parsed_image_without_size["main_window"]
    
    image_with_questions_mark = """
    ( (image:?x?)[image="http://www.adobetes.com/f45iaw100/ex1_02_video.flv"] )
    """
    parsed_image_with_questions_mark = layout_parser.parse(image_with_questions_mark)
    main_window_image_with_questions_mark = parsed_image_with_questions_mark["main_window"]
    return main_window_image_without_size, main_window_image_with_questions_mark
    
    def test_native_dimensions_without_size_image(self):
      main_window_image_without_size, main_window_image_with_questions_mark = self.image_native_dimensions_init()
      self.assertEquals(main_window_image_without_size.calculate_size(), main_window_image_without_size.calculate_box_size())
        
    def test_native_dimensions_with_queasion_marks_image(self):
      main_window_image_without_size, main_window_image_with_questions_mark = self.image_native_dimensions_init()
      self.assertEquals(main_window_image_with_questions_mark.calculate_size(), main_window_image_with_questions_mark.calculate_box_size())
    
    def test_native_dimensions_image(self):
      main_window_image_without_size, main_window_image_with_questions_mark = self.image_native_dimensions_init()
      self.assertEquals(main_window_image_without_size.calculate_size(), main_window_image_with_questions_mark.calculate_size())
      self.assertEquals(main_window_image_without_size.calculate_box_size(), main_window_image_with_questions_mark.calculate_box_size())
 
    
  def test_over_constraining_missing_width(self):
    hight_over_constrained = """
      ( (label:?x20)
        ------------
        (label:?x20)
        ------------
        (label:?x20) ) :50x50
    """
    parsed = layout_parser.parse(hight_over_constrained)
    main_window = parsed["main_window"]
    self.assertEquals(len(main_window), 3)
    self.assertEquals(type(main_window[0]), atoms.Label)
    self.assertEquals(main_window.calculate_size(), (50, 60))
    self.assertEquals(main_window.calculate_box_size(), (50, 50))
    
  def test_over_constraining_missing_hight(self):
    width_over_constrained = """
      ( (label:20x?)
        ------------
        (label:20x?)
        ------------
        (label:20x?) ) :50x50
    """
    parsed = layout_parser.parse(width_over_constrained)
    main_window = parsed["main_window"]
    self.assertEquals(len(main_window), 3)
    self.assertEquals(type(main_window[0]), atoms.Label)
    self.assertEquals(main_window.calculate_box_size(), (50, 50))
    
  def test_over_constraining(self):
    width_hight_over_constrained = """
      ( (label:20x20)
        ------------
        (label:20x20)
        ------------
        (label:20x20) ) :50x50
    """
    parsed = layout_parser.parse(width_hight_over_constrained)
    main_window = parsed["main_window"]
    self.assertEquals(len(main_window), 3)
    self.assertEquals(type(main_window[0]), atoms.Label)
    self.assertEquals(main_window[0].calculate_size(), (20, 20))
    self.assertEquals(main_window[1].calculate_size(), (20, 20))
    self.assertEquals(main_window[2].calculate_size(), (20, 20))
    self.assertEquals(main_window.calculate_size(), (50, 60))
    self.assertEquals(main_window.calculate_box_size(), (50, 50))
    
  def test_over_constraining_long_text(self):
    code = r"""
      ( (label:500x150)[text="Rolling Stones Paint It Black Lyrics"]
        --------------------------------------------------------------------------------------------------------------------------------
        (image)[image="test_data\\icons\\cellphone.png"]|(button:?x50)[text="Send Paint It Black Ringtone to your Cell"]
        --------------------------------------------------------------------------------------------------------------------------------
        (textbox:500x700)[text="I see a red door and I want it painted black\nNo colors anymore I want them to turn black\nI see the girls walk by dressed in their summer clothes\nI have to turn my head until my darkness goes\nI see a line of cars and they're all painted black\nWith flowers and my love both never to come back\nI see people turn their heads and quickly look away\nLike a new born baby it just happens every day\nI look inside myself and see my heart is black\nI see my red door and must have it painted black\nMaybe then I'll fade away and not have to face the facts\nIt's not easy facin' up when your whole world is black\nNo more will my green sea go turn a deeper blue\nI could not foresee this thing happening to you\nIf I look hard enough into the settin' sun\nMy love will laugh with me before the mornin' comes\nI see a red door and I want it painted black\nNo colors anymore I want them to turn black\nI see the girls go by dressed in their summer clothes\nI have to turn my head until my darkness goes\nHmm, hmm, hmm,...\nI wanna see it tainted, tainted black\nBlack as night, black as coal\nI wanna see the sun blotted out from the sky\nI wanna see it tainted, tainted, tainted, tainted black\nYeah!\nHmm, hmm, hmm,..."]
                                                                 ):300x700
    """ 
    parsed = layout_parser.parse(code)
    main_window = parsed["main_window"]
    self.assertEquals(len(main_window), 3)
    self.assertEquals(len(main_window[1]), 2)
    self.assertEquals(main_window.calculate_box_size(), (300, 700))
    self.assertEquals(main_window[0].calculate_size(), (500, 150))
    self.assertEquals(main_window[2].calculate_size(), (500, 700))
    
  def test_over_constraining_padding(self):
    code = """
    L <-  ( (label:?x?)[text="Do you like"]
            ----------------------------------------------------------------------------------------------------------------
            (radio)[checked=x]|(label:20x10)[text="Yes"]|(radio)[checked=(!x && (x || !x))]|(label:20x?)[text="No"]  ) :50x60
        
    I <-   (button:30x?)[text="Tell a friend"]
    
    main_window <- ((L)|(I)) :100x60
    """
    parsed = layout_parser.parse(code)
    main_window = parsed["main_window"]
    self.assertEquals(len(main_window), 2)
    self.assertEquals(len(main_window[0][1]), 4)
    self.assertEquals(main_window.calculate_box_size(), (100, 60))
    self.assertEquals(main_window[0][1].calculate_size(), (50, 10))
    self.assertEquals(main_window[1].calculate_size(), (30, 60))
  
    
  def test_multi_line_text(self):
    code = r"""
      (label)[text="bulshit\nbulshit"]
    """
    parsed = layout_parser.parse(code)
    main_window = parsed["main_window"]


  def test_under_constraining(self):
    
    code = """
      ( (label:?x?)
        ----------
        (label:?x?) ) :50x50
    """
    parsed = layout_parser.parse(code)
    main_window = parsed["main_window"]
    self.assertEquals(len(main_window), 2)
    self.assertEquals(main_window.calculate_box_size(), (50, 50))
    
  def test_reserved_words(self):
    code = """
      ( (button:32x32)[value=(open), image="test_data\\icons\open.jpg"]|():10x?|
        (button:32x32)[value=(if), image="test_data\\icons\open.jpg"]|
        (button:32x32)[value=(elif), image="test_data\\icons\open.jpg"]|
        (button:32x32)[value=(else), image="test_data\\icons\open.jpg"]|():10x?|
        (button:32x32)[value=(type), image="test_data\\icons\open.jpg"]
        ------------------------------------------------------------------------------------
        (textbox)[text="Redrum", font="(Arial, 16px, bold)"]
        ------------------------------------------------------------------------------------
        (label)[text="Status : ready"]):300x200  [open=?(0), if=?(0), elif=?(0), else=?(0), type=?(0)] 
    """  
    self.assertNotEquals(layout_parser.parse(code), None)
    
  def test_bgcolor_for_empty_widget(self):
    code="""
    (                            ():?x(B)
            ----------------------------------------------------------------------------
            ():(B)x?|(image)[image="test_data\\icons\\steve_jobs.jpg"]|():(B)x?
            ----------------------------------------------------------------------------
                                ():?x(B)                                                )[bgcolor="green"]
    """
    parsed = layout_parser.parse(code)
    main_window = parsed["main_window"]


if __name__ == '__main__':
  import unittest
  unittest.main()
